package com.atguigu.juc;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ：MJS
 * @date ：Created in 2021/5/3  11:41
 * @description：TODO
 * 1.验证Volatile的可见性
 * 1.1假如int number=0   number变量之前没有添加volatile关键词修饰
 * 1.2  添加volatile可以保证可见性问题
 * 2.验证volatile不保证原子性
 * 2.1 原子性指的是什么
 *      不可分割，完整性，也即某一个线程正在做某个具体业务时，中间不可以被加塞或分割，需要整体完整性
 * 2.2 volatile  不保证原子性
 * 2.3如何解决原子性问题
 * 2.3.1 synchronized
 * 2.3.2 使用juc下面的atomicInteger
 */
//

public class VolatileDemo {

    public static void main(String[] args) {
        ReSort reSort =new ReSort();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                reSort.method1();
                reSort.method2();
            }, String.valueOf(i)).start();
        }
    }

    private static void atomic() {
        MyData myData=new MyData();
        for (int i = 1; i <= 20; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    myData.addPlus();
                    myData.addAtomic();
                }
            }, String.valueOf(i)).start();
        }
        //需要等待上面20个线程全部计算完成后，再用main线程取得最终的结果值是多少
        while (Thread.activeCount()>2){
            Thread.yield();//线程礼让
        }
        System.out.println(Thread.currentThread().getName()+"\t"+"int type task is over"+myData.number);
        System.out.println(Thread.currentThread().getName()+"\t"+"atomicInteger task is over"+myData.atomicInteger);
    }

    //可以保证可见性，即使通知其他内存主内存中的数据已经改变
    private static void seeOkByVolatile() {
        MyData myData=new MyData();
        new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"\t"+"insert in "+myData.number);
        try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace();}
        myData.addTo60();
        System.out.println(Thread.currentThread().getName()+"\t"+"update "+myData.number);

        },"A").start();

        while(myData.number==0){

        }
        System.out.println(Thread.currentThread().getName()+"\t"+"mission is over");
    }
}


class MyData{//资源类
    volatile int number=0;//volatile保证可见性
    public void addTo60(){
        this.number=60;
    }
    public void addPlus(){
        number++;
    }
    AtomicInteger atomicInteger=new AtomicInteger();//默认为0
    public void addAtomic(){
        atomicInteger.getAndIncrement();
    }
}

class ReSort{
    int a=0;
    boolean flag=false;
    public void method1(){
        a=1;
        flag=true;
    }
    //多线程环境种线程交替执行，由于编译器优化重排的存在
    //两个线程中使用的变量能否保证一致性是无法确定的，结果无法预测
    public void method2(){
        if(flag){
            a=a+5;
            System.out.println("result="+a);
        }
    }
}

